package com.lx.idea.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lx.idea.common.Constant;
import com.lx.idea.mapper.AnalysisMapper;
import com.lx.idea.mapper.NodeMapper;
import com.lx.idea.model.*;
import com.lx.idea.model.mongodb.MongodbAnalysis;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @Author ybb
 * @Description
 * @Date 2021/9/2 17:10
 */
@Service
@Slf4j
public class AnalysisServiceImpl  {

    @Autowired
    AnalysisMapper analysisMapper;

    @Autowired
    NodeMapper nodeMapper;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    NodeServiceImpl nodeService;

    @Transactional
    public AnalysisTb save(AnalysisTb analysisTb){
        CurrentNode currPrefix = nodeMapper.getCurrPrefix();
        if (!analysisTb.getAnalysisPath().startsWith(currPrefix.getPrefixSelf())){
            return null;
        }
        if (Constant.level_2 == currPrefix.getLevel()){
            //如果当前是二级节点并且下级节点是虚拟节点
            Node nextNode = nodeService.getNextNode(analysisTb.getAnalysisPath(),currPrefix.getLevel());
            if (Constant.virtualType != nextNode.getNodeType()){
                return null;
            }
        }
        if (analysisTb.getTemplateId() != null) {
            //正则表达式匹配 标识
            AnalysisTemplate template = analysisMapper.getOne(analysisTb.getTemplateId());
            if (null == template) return null;
            log.info("模板内容 => {}",template);
            Boolean pattern = Pattern.matches(template.getTemplateRegx(),analysisTb.getData());
            log.info("内容匹配结果 pattern => {}",pattern);
            if (!pattern) return null;
        }
        AnalysisTb tb = getByPath(analysisTb.getAnalysisPath());
        if (ObjectUtils.isNotEmpty(tb)){
            //已存在
            analysisTb.setId(tb.getId());
            analysisMapper.updateById(analysisTb);
        }else {
            analysisMapper.insert(analysisTb);
        }

        // TODO: 2021/9/7  这里还需要插入mongodb
        MongodbAnalysis analysis = new MongodbAnalysis();
        analysis.setAnalysisPath(analysisTb.getAnalysisPath());
        analysis.setAnalysisData(analysisTb.getData());

        log.info("插入更新 mongodb {}",analysis);
        Query query = new Query();
        query.addCriteria(Criteria.where("analysisPath").is(analysis.getAnalysisPath()));
        Update update = Update.update("analysisData", analysis.getAnalysisData());
        mongoTemplate.upsert(query, update, "analysis");

//        null == tb ? mongoTemplate.save(analysis): mongoTemplate.update(analysis);
        return analysisTb;
    }

    public int del(String analysisPath){
        AnalysisTb analysisTb = getByPath(analysisPath);
        if (null == analysisTb) return 0;
        Query query = Query.query(Criteria.where("analysisPath").is(analysisTb.getAnalysisPath()));
        mongoTemplate.remove(query, MongodbAnalysis.class);
        return analysisMapper.deleteById(analysisTb.getId());
    }

    public AnalysisTb getByPath(String path){
        QueryWrapper<AnalysisTb> queryWrapper = new QueryWrapper<AnalysisTb>().eq("analysis_path",path);
        return  analysisMapper.selectOne(queryWrapper);
    }

    public List<AnalysisTb> getList(){
        return  analysisMapper.getPageList();
    }

    public Map registerCount(String minDate, String maxDate){
        Map map = new HashMap<>();
        List<String> k = new ArrayList<>();
        List<Long> v = new ArrayList<>();
       List<StatisticCount> list = analysisMapper.getCount(minDate,maxDate);
        list.forEach( s -> {
            k.add(s.getDateTime());
            v.add(s.getCount());
        });
        map.put("date",k);
        map.put("count",v);
        return map;
    }
}
